import re

from rest_framework.exceptions import ValidationError
from rest_framework import serializers
from ..models import UserModel
from .department import DeptSerializer
from .role import BaseRolesSerializer


class UserRegisterSerializer(serializers.ModelSerializer):
    """
    用户注册的序列化类
    """

    class Meta:
        model = UserModel
        fields = ["id", "username", "password", "phone", "real_name"]
        extra_kwargs = {
            "username": {
                "max_length": 12,
                "min_length": 2
            },
            "password": {
                "max_length": 8,
                "min_length": 6,
                "write_only": True
            }
        }

    def validate_phone(self, phone):
        """
        验证手机号码， 自定义一个验证的函数（命名规则：validate_ + 字段名）
        :param phone:
        :return:
        """
        if not phone:
            return phone
        else:
            if not re.match(r"^1[3589]\d{9}$", phone):
                raise ValidationError("请输入正确的手机号码")
        return phone

    def create(self, validated_data):
        """
        必须重写创建方法， 因为用户密码是不能直接插入数据库中的
        :param validated_data:
        :return:
        """
        user = UserModel.objects.create_user(**validated_data)
        return user


class UserUpdateOrDeleteSerializer(serializers.ModelSerializer):
    """
    只用于修改和删除， 修改包括：id, real_name, role_id, dept_id
    """
    dept = DeptSerializer(many=False, read_only=True)

    class Meta:
        model = UserModel
        fields = ['id', "phone", "real_name", "roles", "dept"]


class UserGetSerializer(serializers.ModelSerializer):
    """
    只用于查询用户， 返回： id, username, phone, real_name, 所有的角色的详细信息， 用户所在部门的详细信息
    """
    roles = BaseRolesSerializer(many=True, read_only=True)
    dept = DeptSerializer(many=False, read_only=True)

    class Meta:
        model = UserModel
        fields = ['id', 'username', "phone", "real_name", "roles", "dept"]


class ResetPasswordSerializer(serializers.ModelSerializer):
    """
    只用于修改密码, 包含3个参数： 原密码， 新密码， 新密码确认
    """
    new_password = serializers.CharField(required=True, write_only=True)
    confirm_password = serializers.CharField(required=True, write_only=True)

    class Meta:
        model = UserModel
        fields = ["id", "new_password", "password", "confirm_password"]
        extra_kwargs = {
            "password": {"write_only": True},
            "confirm_password": {"write_only": True},
            "new_password": {"write_only": True},
        }

    def validate(self, attrs):
        """
        表单参数的验证
        :param attrs:
        :return:
        """
        password = attrs.get("password")
        confirm_password = attrs.get("confirm_password")
        new_password = attrs.get("new_password")
        if not password:
            raise ValidationError("字段password为必填字段")
        if not confirm_password:
            raise ValidationError("字段confirm_password为必填字段")
        if not new_password:
            raise ValidationError("字段new_password为必填字段")
        if confirm_password != new_password:
            raise ValidationError('输入密码不一致')
        return attrs

    def save(self, **kwargs):
        # 必须重写save函数， 否则明文密码保存在数据库中
        if not self.instance.check_password(self.validated_data.get('password')):
            raise ValidationError("原始密码错误，请重新输入原始密码")
        self.instance.set_password(self.validated_data.get("new_password"))
        self.instance.save()
        return self.instance
